using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using FacebookWrapper;
using FacebookWrapper.ObjectModel;

namespace B12_Ex03_Eran_053094363_Assaf_036722999
{
    public class FacebookManager
    {
        private static FacebookManager s_Instance = null;
        private static object s_LockObject = new object();

        private User m_LoggedInUser;
        private string m_AccessToken;

        public enum eFacebookObject
        {
            Friend,
            Post,
            Checkin,
            Event,
            NewsFeed
        }

        private FacebookManager()
        {
            m_AccessToken = Properties.Settings.Default.FacebookUserToken;
        }

        // Singleton Instance with double-check locking
        public static FacebookManager Instance
        {
            get
            {
                if (s_Instance == null)
                {
                    lock (s_LockObject)
                    {
                        if (s_Instance == null)
                        {
                            s_Instance = new FacebookManager();
                        }
                    }
                }

                return s_Instance;
            }
        }

        /// <summary>
        /// Login to the Facebook Application
        /// </summary>
        /// <param name="i_AppAccessToken">The Application Accesss token given when the application was created in facebook</param>
        /// <returns>True if the Login was successfull</returns>
        /// <exception cref="Exception">Throws an Error if Login fails</exception>
        public bool Login(string i_AppAccessToken)
        {
            LoginResult result = null;
            bool loginOK = false;
            if (string.IsNullOrEmpty(Properties.Settings.Default.FacebookUserToken))
            {
                // Connect to facebook using the Application ID and the Requested Access Permissions
                result = FacebookWrapper.FacebookService.Login(
                    i_AppAccessToken, // The Application Access Token
                    "user_about_me", "friends_about_me", // Basic User Information
                    "publish_stream", // Publish new stream_posts
                    "user_events", // Get Events
                    "read_stream", // Get my News Feed
                    "user_status", // this is instead of the 'user_checkins' permission, as desricbed here: http://developers.facebook.com/bugs/170251059758531
                    "read_friendlists", // Get my Freinds List
                    "user_photos", "friends_photos", // get Photos
                    "user_education_history", "friends_education_history", // Get Education Information
                    "user_interests", "friends_interests", // Get the Interests of a user Information
                    "user_relationships", "friends_relationships", // Get Relationship Information
                    "user_relationship_details", "friends_relationship_details", // Get Detailed Relationship Information
                    "email", // Get User Email Information
                    "offline_access"); // Stay Logged in until a Logoff Request is submitted
            }
            else
            {
                // Connect to Facebook using the Saved User Access Token
                result = FacebookWrapper.FacebookService.Connect(m_AccessToken);
            }

            // Check the Login Result 
            if (result != null)
            {
                if (string.IsNullOrEmpty(result.ErrorMessage))
                {
                    if (result.LoggedInUser != null)
                    {
                        m_LoggedInUser = result.LoggedInUser;
                        m_AccessToken = result.AccessToken;
                        Properties.Settings.Default.FacebookUserToken = m_AccessToken;
                        Properties.Settings.Default.Save();
                        loginOK = true;
                    }
                    else
                    {
                        throw new Exception("Ooops...\n\nFacebook is having some Problems Logging in.\nTry agian later...");
                    }
                }
                else
                {
                    throw new Exception(result.ErrorMessage);
                }
            }

            return loginOK;
        }

        /// <summary>
        /// Log out the User
        /// And clear the saved Token
        /// </summary>
        public void Logout()
        {
            Properties.Settings.Default.FacebookUserToken = m_AccessToken = null;
        }

        /// <summary>
        /// stream_post a new stream_post the the Logged on User Status
        /// </summary>
        /// <param name="i_stream_postMessage">The Message to stream_post</param>
        public void PostNewMessageStatus(string i_PostMessage)
        {
            if (m_LoggedInUser != null)
            {
                m_LoggedInUser.PostStatus(i_PostMessage);
            }
        }

        /// <summary>
        /// Returns the Profile Picture URL
        /// </summary>
        /// <returns></returns>
        public string GetProfilePicture()
        {
            return m_LoggedInUser.PictureNormalURL;
        }

        /// <summary>
        /// Returns if the Application has the abillity to 
        /// login automatically using a Token
        /// </summary>
        /// <returns></returns>
        public bool HasAutoLogin()
        {
            return !string.IsNullOrEmpty(m_AccessToken);
        }

        /// <summary>
        /// Get all The Logged on User Friends
        /// </summary>
        /// <returns>A List of Facebook <see cref="User"/> Friends of the Logged on User</returns>
        public List<User> GetFriends()
        {
            return new FacebookObjectProxy(m_LoggedInUser).GetFriends();
        }

        /// <summary>
        /// Get all the Friends of the Logged on user and thier friends also
        /// </summary>
        /// <returns>A List of Facebook <see cref="User"/> friends of the Logged on Usr and thier Friends also</returns>
        public List<User> GetFriendsOfFriends()
        {
            return new FacebookObjectProxy(m_LoggedInUser).GetFriendsOfFriends();
        }

        /// <summary>
        /// Get all the Logged on User Events
        /// </summary>
        /// <returns>A List of Facebook <see cref="Event"/> of the Logged on User</returns>
        public List<Event> GetEvents()
        {
            return new FacebookObjectProxy(m_LoggedInUser).GetEvents();
        }

        /// <summary>
        /// Get the Logged on Facebook User News Feed
        /// </summary>
        /// <returns>A List of string News Feed Messages</returns>
        public NewsFeed GetNewsFeed()
        {
            return new FacebookObjectProxy(m_LoggedInUser).GetNewsFeed();
        }

        /// <summary>
        /// Get all The Logged on User Check in
        /// </summary>
        /// <returns>A List of Facebook <see cref="Checkin"/> of the Logged on User</returns>
        public List<Checkin> GetCheckIns()
        {
            return new FacebookObjectProxy(m_LoggedInUser).GetCheckIns();
        }

        /// <summary>
        /// Get all the Friends Posts
        /// </summary>
        /// <returns></returns>
        public List<Post> GetFriendsPost(int i_PostsCount)
        {
            return new FacebookObjectProxy(m_LoggedInUser).GetFriendsPost(i_PostsCount);
        }
    }
}
